from pydantic import BaseModel, EmailStr
from typing import List, Optional
from datetime import datetime
from typing import Generic, TypeVar
from pydantic.generics import GenericModel

# 用户相关
class UserBase(BaseModel):
    name: str
    phone: str
    category: str
    sec_type: Optional[int] = 0
    desc: Optional[str] = ""
    icon_path: Optional[str] = None

class UserCreate(UserBase):
    username: str
    password: str

class UserUpdate(BaseModel):
    name: Optional[str] = None
    phone: Optional[str] = None
    category: Optional[str] = None
    sec_type: Optional[int] = None
    desc: Optional[str] = None
    role_ids: Optional[List[int]] = None
    icon_path: Optional[str] = None
    student_phone: Optional[str] = None  # 学生手机号（仅家长用户使用）

class UserInDB(UserBase):
    id: int
    username: str
    is_active: bool
    
    class Config:
        orm_mode = True

class User(UserInDB):
    roles: List['Role'] = []

# 角色相关
class RoleBase(BaseModel):
    name: str

class RoleCreate(RoleBase):
    pass

class Role(RoleBase):
    id: int
    
    class Config:
        orm_mode = True

class RoleWithUsers(Role):
    users: List[UserInDB] = []

# 登录相关
class LoginRequest(BaseModel):
    username: str
    password: str
    captcha: str
    captcha_key: str

class Token(BaseModel):
    access_token: str
    token_type: str

class TokenData(BaseModel):
    username: Optional[str] = None

# 关联 User 和 Role 模型
User.update_forward_refs()
RoleWithUsers.update_forward_refs()

# 文件相关
class FileBase(BaseModel):
    uuid: str
    filename: str
    file_path: str
    file_size: int
    file_type: Optional[str] = None
    display_name: Optional[str] = None
    saved_filename: Optional[str] = None
    description: Optional[str] = None
    watch_num: int

class FileCreate(FileBase):
    pass

class FileUpdate(BaseModel):
    display_name: Optional[str] = None
    description: Optional[str] = None

class FileInDB(FileBase):
    id: int
    created_at: datetime
    updated_at: datetime
    uploader_id: Optional[int] = None
    
    class Config:
        orm_mode = True

class File(FileInDB):
    uploader: Optional[UserInDB] = None

# 信息发布相关
class NoticeBase(BaseModel):
    title: str
    pushOrg: str
    pushTime: datetime
    type: int
    icon_path: Optional[str] = None
    link_url: Optional[str] = None

class NoticeCreate(NoticeBase):
    pass

class NoticeUpdate(BaseModel):
    title: Optional[str] = None
    pushOrg: Optional[str] = None
    pushTime: Optional[datetime] = None
    type: Optional[int] = None
    icon_path: Optional[str] = None
    link_url: Optional[str] = None

class NoticeInDB(NoticeBase):
    id: int
    is_active: bool
    created_at: datetime
    updated_at: datetime
    creator_id: Optional[int] = None
    
    class Config:
        orm_mode = True

class Notice(NoticeInDB):
    creator: Optional[UserInDB] = None

# 小程序（mp）相关通用请求/响应模型
T = TypeVar('T')

class MPResponse(GenericModel, Generic[T]):
    code: str
    msg: str
    data: Optional[T] = None

class MPLoginRequest(BaseModel):
    jsCode: str
    phone: Optional[str] = ""

class MPRegisterRequest(BaseModel):
    phone: str
    nickname: str
    profile: Optional[str] = ""
    category: Optional[int] = 0
    skey: Optional[str] = ""

class MPDecryptPhoneRequest(BaseModel):
    phoneDataIV: str
    phoneData: str
    skey: str

class MPCoursesAddRequest(BaseModel):
    phone: str
    newCourse: dict

class MPBookingTeachRequest(BaseModel):
    userName: str
    userPhone: str
    selectDate: str
    affairsId: str

class MPSubmitPunchWordsRequest(BaseModel):
    phone: str

class MPTodayRequest(BaseModel):
    today: str

class MPPhoneRequest(BaseModel):
    phoneNumber: str

class MPBaseIdRequest(BaseModel):
    baseId: str
    userType: int = 0

class MPSearchRequest(BaseModel):
    offset: int = 0
    limit: int = 0
    searchKey: str = ""

# 用户关联相关（家长-学生）
class UserRelationBase(BaseModel):
    parent_phone: str
    student_phone: str

class UserRelationCreate(UserRelationBase):
    pass

class UserRelationUpdate(BaseModel):
    student_phone: Optional[str] = None

class UserRelationInDB(UserRelationBase):
    id: int
    created_at: datetime
    updated_at: datetime
    
    class Config:
        orm_mode = True

class UserRelation(UserRelationInDB):
    pass

# 课程相关
class CourseBase(BaseModel):
    cover: Optional[str] = None
    title: str
    desc: Optional[str] = None
    price: int
    book_num: Optional[int] = 0

class CourseCreate(CourseBase):
    pass

class CourseUpdate(BaseModel):
    cover: Optional[str] = None
    title: Optional[str] = None
    desc: Optional[str] = None
    price: Optional[int] = None
    book_num: Optional[int] = None

class CourseInDB(CourseBase):
    id: int
    is_active: bool
    created_at: datetime
    updated_at: datetime
    creator_id: Optional[int] = None
    
    class Config:
        orm_mode = True

class Course(CourseInDB):
    creator: Optional[UserInDB] = None

# 课程章节相关
class CourseCategoryBase(BaseModel):
    code: str
    name: str
    can_view: bool = False
    content: Optional[str] = None
    url: Optional[str] = None
    sort_order: Optional[int] = 0

class CourseCategoryCreate(CourseCategoryBase):
    pass

class CourseCategoryUpdate(BaseModel):
    code: Optional[str] = None
    name: Optional[str] = None
    can_view: Optional[bool] = None
    content: Optional[str] = None
    url: Optional[str] = None
    sort_order: Optional[int] = None

class CourseCategoryInDB(CourseCategoryBase):
    id: int
    course_id: int
    is_active: bool
    created_at: datetime
    updated_at: datetime
    
    class Config:
        orm_mode = True

class CourseCategory(CourseCategoryInDB):
    pass

# 预约相关
class BookingBase(BaseModel):
    from_phone: str
    book_date: str
    to_phone: str

class BookingCreate(BookingBase):
    pass

# 打卡相关
class PunchBase(BaseModel):
    phone: str
    punch_date: str
    type: Optional[int] = 0

class PunchCreate(PunchBase):
    pass


# 排课相关
class ScheduleBase(BaseModel):
    phone: str
    course_name: str
    date: str
    time_slot: str

class ScheduleCreate(ScheduleBase):
    pass
